/*
 * Copyright (C) 2022, KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

//
// Created by hxf on 22-11-11.
//

#ifndef UKUI_SIDEBAR_SIDEBAR_WINDOW_H
#define UKUI_SIDEBAR_SIDEBAR_WINDOW_H

#include <QRect>
#include <QQuickWindow>

#include "window-type.h"

namespace Sidebar {

/**
 * 1.管理不同平台设置geometry的接口
 * 2.为某类型的窗口提供geometry属性
 */
class SidebarWindowHelper : public QObject
{
    Q_OBJECT
public:
    static SidebarWindowHelper *instance(QObject *parent = nullptr);

    static void setWindowGeometry(QWindow *window, const QRect& rect);
    static void setWindowFlags(QWindow *window, SidebarWindowType::Type type);
    static void setWindowAttribute(QWindow *window, SidebarWindowType::Type type);

    QRect getWindowGeometry(SidebarWindowType::Type type);
    void updateWindowGeometry(QWindow *window, SidebarWindowType::Type type);

Q_SIGNALS:
    void geometryChanged();

private Q_SLOTS:
    void updateRects();

private:
    explicit SidebarWindowHelper(QObject *parent = nullptr);

private:
    QRect m_statusBarRect;
    QRect m_rightGestureRect;
    QRect m_notificationCenterRect;
};

class SidebarWindowBase : public QQuickWindow
{
    Q_OBJECT
public:
    explicit SidebarWindowBase(QWindow *parent = nullptr);
    explicit SidebarWindowBase(SidebarWindowType::Type type, QWindow *parent = nullptr);

protected:
    SidebarWindowType::Type windowType();
    bool event(QEvent *event) override;
    void exposeEvent(QExposeEvent *event) override;
    virtual QRect windowGeometry();

protected Q_SLOTS:
    // 可以覆盖该方法使用自定义的rect
    void updateGeometry();

protected:
    SidebarWindowType::Type m_windowType;

private:
    void initBase();
};

class StatusBarWindow : public SidebarWindowBase
{
    Q_OBJECT
public:
    explicit StatusBarWindow(QWindow *parent = nullptr);
};

class RightHandGestureWindow : public SidebarWindowBase
{
    Q_OBJECT
public:
    explicit RightHandGestureWindow(QWindow *parent = nullptr);
};

class NotificationCenterWindow : public SidebarWindowBase
{
    Q_OBJECT
public:
    explicit NotificationCenterWindow(QWindow *parent = nullptr);
};

class SidebarWindow : public SidebarWindowBase
{
    Q_OBJECT
    Q_PROPERTY(bool contentVisible READ contentVisible WRITE setContentVisible NOTIFY contentVisibleChanged)
    Q_PROPERTY(bool isTabletMode READ isTabletMode NOTIFY isTabletModeChanged)
    Q_PROPERTY(qint32 windowPadding READ windowPadding NOTIFY windowPaddingChanged)
    Q_PROPERTY(qint32 minimumThreshold READ minimumThreshold NOTIFY minimumThresholdChanged)
    Q_PROPERTY(qint32 primaryScreenRight READ primaryScreenRight NOTIFY primaryScreenRightChanged)
    Q_PROPERTY(QRect sidebarContentGeometry READ sidebarContentGeometry NOTIFY sidebarContentGeometryChanged)
    Q_PROPERTY(QRect sidebarWindowGeometry READ sidebarWindowGeometry NOTIFY sidebarWindowGeometryChanged)
public:
    explicit SidebarWindow(QWindow *parent = nullptr);

    bool isTabletMode();
    bool contentVisible();
    void setContentVisible(bool visible);

    qint32 windowPadding();
    qint32 minimumThreshold();
    qint32 primaryScreenRight();
    QRect sidebarContentGeometry();
    QRect sidebarWindowGeometry();

Q_SIGNALS:
    void isTabletModeChanged();
    void contentVisibleChanged();
    void windowPaddingChanged();
    void minimumThresholdChanged();
    void primaryScreenRightChanged();
    void sidebarContentGeometryChanged();
    void sidebarWindowGeometryChanged();
    void requestShowContent();
    void requestHideContent();

protected:
    void focusInEvent(QFocusEvent *event) override;
    void focusOutEvent(QFocusEvent *event) override;

private:
    void initWindow();

private Q_SLOTS:
    void updateWindowGeometry();

private:
    bool m_contentVisible{false};
};

class SidebarWindowDefineModule
{
public:
    static void defineModules(const char *uri, int versionMajor, int versionMinor);
};

} // Sidebar

#endif //UKUI_SIDEBAR_SIDEBAR_WINDOW_H
